From e493b9b702cfed30c9ddcf5d1715379f2cda3f41 Mon Sep 17 00:00:00 2001 From: Zander Brown Date: Wed, 3 Apr 2019 23:50:24 +0100 Subject: [PATCH] inspector: Type info for misc pane Replaces the class hierarchy page with a button/popover on the misc page --- gtk/inspector/meson.build | 1 + gtk/inspector/misc-info.c | 17 +++ gtk/inspector/misc-info.ui | 26 +++++ gtk/inspector/type-info.c | 216 +++++++++++++++++++++++++++++++++++++ gtk/inspector/type-info.h | 35 ++++++ gtk/inspector/type-info.ui | 59 ++++++++++ 6 files changed, 354 insertions(+) create mode 100644 gtk/inspector/type-info.c create mode 100644 gtk/inspector/type-info.h create mode 100644 gtk/inspector/type-info.ui diff --git a/gtk/inspector/meson.build b/gtk/inspector/meson.build index b67da21bd4..a26d67ed87 100644 --- a/gtk/inspector/meson.build +++ b/gtk/inspector/meson.build @@ -31,6 +31,7 @@ inspector_sources = files( 'statistics.c', 'strv-editor.c', 'treewalk.c', + 'type-info.c', 'updatesoverlay.c', 'visual.c', 'window.c', diff --git a/gtk/inspector/misc-info.c b/gtk/inspector/misc-info.c index 1d9d053d7d..f082553a6b 100644 --- a/gtk/inspector/misc-info.c +++ b/gtk/inspector/misc-info.c @@ -21,6 +21,7 @@ #include "misc-info.h" #include "window.h" #include "object-tree.h" +#include "type-info.h" #include "gtktypebuiltins.h" #include "gtktreeview.h" @@ -28,6 +29,7 @@ #include "gtklabel.h" #include "gtkframe.h" #include "gtkbutton.h" +#include "gtkmenubutton.h" #include "gtkwidgetprivate.h" @@ -37,6 +39,8 @@ struct _GtkInspectorMiscInfoPrivate { GObject *object; GtkWidget *address; + GtkWidget *type; + GtkWidget *type_popover; GtkWidget *refcount_row; GtkWidget *refcount; GtkWidget *state_row; @@ -260,11 +264,18 @@ update_info (gpointer data) { GtkInspectorMiscInfo *sl = data; gchar *tmp; + GType gtype; tmp = g_strdup_printf ("%p", sl->priv->object); gtk_label_set_text (GTK_LABEL (sl->priv->address), tmp); g_free (tmp); + gtype = G_TYPE_FROM_INSTANCE (sl->priv->object); + + gtk_button_set_label (GTK_BUTTON (sl->priv->type), g_type_name (gtype)); + gtk_inspector_type_popover_set_gtype (GTK_INSPECTOR_TYPE_POPOVER (sl->priv->type_popover), + gtype); + if (G_IS_OBJECT (sl->priv->object)) { tmp = g_strdup_printf ("%d", sl->priv->object->ref_count); @@ -458,6 +469,11 @@ gtk_inspector_misc_info_init (GtkInspectorMiscInfo *sl) { sl->priv = gtk_inspector_misc_info_get_instance_private (sl); gtk_widget_init_template (GTK_WIDGET (sl)); + + sl->priv->type_popover = g_object_new (GTK_TYPE_INSPECTOR_TYPE_POPOVER, NULL); + gtk_menu_button_set_popover (GTK_MENU_BUTTON (sl->priv->type), + sl->priv->type_popover); + } static void @@ -540,6 +556,7 @@ gtk_inspector_misc_info_class_init (GtkInspectorMiscInfoClass *klass) gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/misc-info.ui"); gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, address); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, type); gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, refcount_row); gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, refcount); gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, state_row); diff --git a/gtk/inspector/misc-info.ui b/gtk/inspector/misc-info.ui index cbb3ef65b4..414a5d2fc1 100644 --- a/gtk/inspector/misc-info.ui +++ b/gtk/inspector/misc-info.ui @@ -41,6 +41,32 @@ + + + 0 + + + 10 + 40 + + + Type + start + baseline + 0.0 + 1 + + + + + end + baseline + + + + + + 0 diff --git a/gtk/inspector/type-info.c b/gtk/inspector/type-info.c new file mode 100644 index 0000000000..6f2f8bdbc5 --- /dev/null +++ b/gtk/inspector/type-info.c @@ -0,0 +1,216 @@ +/* + * Copyright © 2019 Zander Brown + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" +#include + +#include "type-info.h" + +#include "gtkpopover.h" + +struct _GtkInspectorTypePopover +{ + GtkPopover parent_instance; +}; + +typedef struct _GtkInspectorTypePopoverPrivate GtkInspectorTypePopoverPrivate; + +struct _GtkInspectorTypePopoverPrivate +{ + GType type; + + GtkWidget *parents; + GtkWidget *interfaces; +}; + +enum +{ + PROP_0, + PROP_TYPE +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorTypePopover, gtk_inspector_type_popover, + GTK_TYPE_POPOVER) + +static void +add_row (GtkContainer *box, + const gchar *name) +{ + GtkWidget *row; + GtkWidget *label; + + row = g_object_new (GTK_TYPE_LIST_BOX_ROW, + "selectable", FALSE, + "activatable", FALSE, + "can-focus", FALSE, + NULL); + + label = g_object_new (GTK_TYPE_LABEL, + "margin", 6, + "label", name, + "selectable", TRUE, + "xalign", 0.0, + NULL); + + gtk_container_add (GTK_CONTAINER (row), label); + gtk_container_add (box, row); +} + +static void +remove_row (GtkWidget *item, + gpointer data) +{ + if (GTK_IS_LIST_BOX_ROW (item)) + gtk_container_remove (GTK_CONTAINER (data), item); +} + +void +gtk_inspector_type_popover_set_gtype (GtkInspectorTypePopover *self, + GType gtype) +{ + GtkInspectorTypePopoverPrivate *priv; + GHashTable *implements; + GHashTableIter iter; + const gchar *name; + GType *interfaces; + GType tmp; + gint i; + + g_return_if_fail (GTK_IS_INSPECTOR_TYPE_POPOVER (self)); + + priv = gtk_inspector_type_popover_get_instance_private (self); + + if (priv->type == gtype) + return; + + priv->type = gtype; + + gtk_container_foreach (GTK_CONTAINER (priv->parents), + remove_row, priv->parents); + gtk_container_foreach (GTK_CONTAINER (priv->interfaces), + remove_row, priv->interfaces); + + implements = g_hash_table_new (g_str_hash, g_str_equal); + + tmp = gtype; + + do + { + add_row (GTK_CONTAINER (priv->parents), g_type_name (tmp)); + + interfaces = g_type_interfaces (tmp, NULL); + + for (i = 0; interfaces[i]; i++) + g_hash_table_add (implements, (gchar *) g_type_name (interfaces[i])); + + g_free (interfaces); + } + while ((tmp = g_type_parent (tmp))); + + g_hash_table_iter_init (&iter, implements); + + while (g_hash_table_iter_next (&iter, (gpointer *) &name, NULL)) + add_row (GTK_CONTAINER (priv->interfaces), name); + + g_hash_table_unref (implements); +} + +static void +gtk_inspector_type_popover_init (GtkInspectorTypePopover *self) +{ + GtkInspectorTypePopoverPrivate *priv; + GtkWidget *label; + + gtk_widget_init_template (GTK_WIDGET (self)); + + priv = gtk_inspector_type_popover_get_instance_private (self); + + priv->type = G_TYPE_NONE; + + label = g_object_new (GTK_TYPE_LABEL, + "margin", 12, + "label", "None", + NULL); + + gtk_list_box_set_placeholder (GTK_LIST_BOX (priv->parents), label); + + label = g_object_new (GTK_TYPE_LABEL, + "margin", 12, + "label", "None", + NULL); + + gtk_list_box_set_placeholder (GTK_LIST_BOX (priv->interfaces), label); +} + +static void +gtk_inspector_type_popover_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + GtkInspectorTypePopover *self = GTK_INSPECTOR_TYPE_POPOVER (object); + GtkInspectorTypePopoverPrivate *priv = gtk_inspector_type_popover_get_instance_private (self); + + switch (param_id) + { + case PROP_TYPE: + g_value_set_gtype (value, priv->type); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +gtk_inspector_type_popover_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkInspectorTypePopover *self = GTK_INSPECTOR_TYPE_POPOVER (object); + + switch (param_id) + { + case PROP_TYPE: + gtk_inspector_type_popover_set_gtype (self, g_value_get_gtype (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +gtk_inspector_type_popover_class_init (GtkInspectorTypePopoverClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->get_property = gtk_inspector_type_popover_get_property; + object_class->set_property = gtk_inspector_type_popover_set_property; + + g_object_class_install_property (object_class, PROP_TYPE, + g_param_spec_gtype ("type", "Type", "Type", + G_TYPE_NONE, G_PARAM_READWRITE)); + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/type-info.ui"); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorTypePopover, parents); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorTypePopover, interfaces); +} diff --git a/gtk/inspector/type-info.h b/gtk/inspector/type-info.h new file mode 100644 index 0000000000..f6d8f41608 --- /dev/null +++ b/gtk/inspector/type-info.h @@ -0,0 +1,35 @@ +/* + * Copyright © 2019 Zander Brown + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef _GTK_INSPECTOR_TYPE_INFO_H_ +#define _GTK_INSPECTOR_TYPE_INFO_H_ + +#include + +G_BEGIN_DECLS + +#define GTK_TYPE_INSPECTOR_TYPE_POPOVER (gtk_inspector_type_popover_get_type ()) + +G_DECLARE_FINAL_TYPE (GtkInspectorTypePopover, gtk_inspector_type_popover, + GTK, INSPECTOR_TYPE_POPOVER, GtkPopover) + +void gtk_inspector_type_popover_set_gtype (GtkInspectorTypePopover *self, + GType gtype); + +G_END_DECLS + +#endif \ No newline at end of file diff --git a/gtk/inspector/type-info.ui b/gtk/inspector/type-info.ui new file mode 100644 index 0000000000..9e62daca0a --- /dev/null +++ b/gtk/inspector/type-info.ui @@ -0,0 +1,59 @@ + + + + -- 2.30.2